home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !preview / c / output < prev    next >
Encoding:
Text File  |  1990-07-27  |  7.6 KB  |  312 lines

  1. /* output.c --- saving and transferring data.  */
  2.  
  3. #include "d2rd.h"
  4. #include <stdio.h>
  5. #include <stdarg.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include "kernel.h"
  9. #include "output.h"
  10. #include "visdelay.h"
  11. #include "font.h"
  12. #include "flex.h"
  13.  
  14. #define VERT_SIZE (int)(A4_HEIGHT*180*256)   /* height of page in Draw internal units */
  15.  
  16. /* Forward declarations.  */
  17.  
  18. void output_sprite (outputter, FILE *);
  19. void output_draw (outputter, FILE *);
  20. size_t ram_write (const void *, size_t, size_t, FILE *);
  21.  
  22. static char *my_buf;
  23. static char *your_buf;
  24. static int buf_size;
  25. static int buf_pos;
  26. static wimp_t dest_task;
  27. static int your_ref;
  28.  
  29.  
  30. void
  31. send_buf (int size)
  32. {
  33.   wimp_msgstr msg;
  34.   wimp_eventstr b;
  35.  
  36.   msg.hdr.action = wimp_MRAMTRANSMIT;
  37.   msg.hdr.your_ref = your_ref;
  38.   msg.hdr.size = sizeof (wimp_msgstr);
  39.   msg.data.ramtransmit.addr = your_buf;
  40.   msg.data.ramtransmit.nbyteswritten = size;
  41.   wimpt_noerr (wimp_transferblock (wimpt_task (), my_buf, dest_task, your_buf, size));
  42.   if (size != buf_size)
  43.     wimpt_noerr (wimp_sendmessage (wimp_ESEND, &msg, dest_task));
  44.   else
  45.     {
  46.       wimpt_noerr (wimp_sendmessage (wimp_ESENDWANTACK, &msg, dest_task));
  47.       for (;;)
  48.         {
  49.           wimpt_noerr (wimp_poll (0x1973, &b));
  50.           switch (b.e)
  51.             {
  52.             case wimp_ESEND:
  53.             case wimp_ESENDWANTACK:
  54.               if (b.data.msg.hdr.your_ref == msg.hdr.my_ref)
  55.                 {
  56.                   dest_task = b.data.msg.hdr.task;                 /* paranoid */
  57.                   your_ref = b.data.msg.hdr.my_ref;
  58.                   your_buf = b.data.msg.data.ramfetch.addr;
  59.                   buf_size = b.data.msg.data.ramfetch.nbytes;
  60.                   my_buf = realloc (my_buf, buf_size);
  61.                   return;
  62.                 }
  63.               else
  64.                 tfatal ("EXPORT FAILED!");
  65. #if 0
  66.                 tfatal ("References fail (%d, %d, %d, %d)", msg.hdr.my_ref, msg.hdr.your_ref, b.data.msg.hdr.my_ref, b.data.msg.hdr.your_ref);
  67. #endif            
  68.             case wimp_EACK:
  69.               fatal ("RAM transfer failed");
  70.               break;
  71.         
  72.             default:
  73. #if 0
  74.               fatal ("unwanted event: %d", b.e);
  75. #endif
  76.               continue;
  77.             }
  78.           break;
  79.         }    
  80.     }
  81. } /* send_buf */
  82.  
  83.  
  84.  
  85. void
  86. output_send (wimp_msgstr *m)
  87. {
  88.   FILE *f = NULL;
  89.  
  90.   your_buf = m->data.ramfetch.addr;
  91.   buf_size = m->data.ramfetch.nbytes;
  92.   dest_task = m->hdr.task;
  93.   your_ref = m->hdr.my_ref;
  94.  
  95.   /* If the buffer on the other size is large enough, we can get rid of the
  96.      sprite at once.  */
  97.  
  98.   if (saveas_filetype == 0xff9 && buf_size > flex_size ((flex_ptr) &which_menu->area))
  99.     {
  100.       buf_pos = 0;
  101.       buf_size = 0;
  102.       my_buf = (char *) &which_menu->area->number;
  103.       send_buf (flex_size ((flex_ptr) &which_menu->area) - 4);
  104.       return;
  105.     }
  106.  
  107.   my_buf = xmalloc (buf_size);
  108.   buf_pos = 0;
  109.  
  110.   visdelay_begin ();
  111.  
  112.   switch (saveas_filetype)
  113.     {
  114.     case 0xff9:
  115.       ram_write (&which_menu->area->number, 1, which_menu->area->size - 4, f);
  116.       break;
  117.     case 0xaff:
  118.       output_draw (&ram_write, f);
  119.       break;
  120.     default:
  121.       tfatal ("But I have never heard of filetype 0x%x!", saveas_filetype);
  122.       break;
  123.     }
  124.  
  125.   wimp_create_menu ((wimp_menustr *) -1, 0, 0);
  126.   send_buf (buf_pos);
  127.   visdelay_end ();
  128.   free (my_buf);
  129. } /* saveas_send */
  130.  
  131.  
  132.  
  133. size_t
  134. ram_write (const void *b, size_t size, size_t nmemb, FILE *f)
  135. {
  136.   int n = size * nmemb, ret = n;
  137.   char *from = (char *)b;
  138.  
  139.   f = f;
  140.  
  141.   for (;;)
  142.     {
  143.       if (buf_pos + n < buf_size)
  144.         {
  145.           for (; n; buf_pos++, from++, n--)
  146.             my_buf[buf_pos] = *from;
  147.           break;
  148.         }
  149.       for (; buf_pos < buf_size; buf_pos++, from++, n--)
  150.         my_buf[buf_pos] = *from;
  151.       send_buf (buf_size);
  152.       buf_pos = 0;
  153.     }
  154.   return (ret);
  155. } /* ram_write */
  156.  
  157.  
  158. void
  159. output_saveas (char *name)
  160. {
  161.   char cmd[300];
  162.   FILE *f;
  163.  
  164.   wimp_create_menu ((wimp_menustr *)-1, 0, 0);
  165.   visdelay_begin ();
  166.  
  167.   f = fopen (name, "wb");
  168.   if (f == NULL)
  169.     {
  170.       fatal ("Can't open file `%s'.", name);
  171.       return;
  172.     }
  173.  
  174.   switch (saveas_filetype)
  175.     {
  176.     case 0xff9:
  177.       fwrite (&which_menu->area->number, 1, which_menu->area->size - 4, f);
  178.       sprintf (cmd, "settype %s ff9", name);
  179.       break;
  180.  
  181.     case 0xaff:
  182.       output_draw (&fwrite, f);
  183.       sprintf (cmd, "settype %s aff", name);
  184.       break;
  185.  
  186.     default:
  187.       tfatal ("But I have never heard of filetype 0x%x!", saveas_filetype);
  188.       break;
  189.     }
  190.   fclose (f);
  191.   _kernel_oscli (cmd);
  192.   visdelay_end ();
  193. } /* output_saveas */
  194.  
  195. /* The routines below are concerned with outputting a draw format file.  */
  196.  
  197. static int
  198. write_n (FILE *f, outputter put_out, int n, ...)
  199. {
  200.   va_list ap;
  201.   int *a, i;
  202.  
  203.   va_start (ap, n);
  204.   a = (int *) xmalloc (n * sizeof (int));
  205.   for (i = 0; i < n; i++)
  206.     a[i] = va_arg (ap, int);
  207.   va_end (ap);
  208.   i = put_out (a, sizeof (int), n, f);
  209.   free (a);
  210.   return (i);
  211. } /* write_n */
  212.  
  213.  
  214.  
  215. void
  216. output_draw (outputter put_out, FILE *f)
  217. {
  218.   struct display *w = which_menu;
  219.   struct page *p = w->page;
  220.   struct dvi_file *df = w->file;
  221.   struct text *txt;
  222.   struct rule *rl;
  223.   int *dvi_to_font = xcalloc (sizeof (int), 256);
  224.   int *font_to_dvi = xcalloc (sizeof (int), 256);
  225.   int max_font = 1, size = 0, rsize, i, j, k, l, t, x, y;
  226.   char *s;
  227.  
  228.   /*
  229.   ** hor_offset holds the horizontal offset for all objects, in
  230.   ** millipoints.  Usually 1in, or 72000 millipoints.
  231.   */
  232.   int hor_offset = w->hor_offset;
  233.  
  234.   /*
  235.   ** ver_offset holds the distance from the bottom of the page to
  236.   ** the offset point, normally 1in from the top edge.  This is
  237.   ** held in millipoints.
  238.   */
  239.   int ver_offset = w->ver_size - w->ver_offset;
  240.  
  241.   /* Output DrawFile header.  */
  242.  
  243.   put_out ("Draw", 1, 4, f);
  244.   write_n (f, put_out, 2, 201, 0);
  245.   put_out ("Preview     ", 1, 12, f);
  246.  
  247. #define VS (11.69*180.0*256.0*(10000.0 / 14142.0))
  248.   write_n (f, put_out, 4, 0, 0, VS, VERT_SIZE); /* avoid constant-overflow! */
  249.  
  250.   /* Build and output the font information object.  */
  251.  
  252.   txt = p->texts;
  253.   for (t = 0; t < p->text_max; t++, txt++)
  254.     if (dvi_to_font[txt->font] == 0)
  255.       {
  256.         font_to_dvi[max_font] = txt->font;
  257.         dvi_to_font[txt->font] = max_font;
  258.         size += 2 + strlen (df->fonts[txt->font]->name);
  259.         max_font++;
  260.       }
  261.   if (size)
  262.     {
  263.       rsize = (size + 3) & ~3;
  264.       write_n (f, put_out, 2, 0, rsize + 8);
  265.       for (i = 1; i < max_font; i++)
  266.         {
  267.           s = df->fonts[font_to_dvi[i]]->name;
  268.           put_out (&i, 1, 1, f);
  269.           put_out (s, 1, 1 + strlen (s), f);
  270.         }
  271.       l = 0;
  272.       for (i = size; i < rsize; i++)
  273.         put_out (&l, 1, 1, f);
  274.     }
  275.  
  276.  
  277.   /* Output the text blobs.  */
  278.  
  279.   for (t = 0, txt = p->texts; t < p->text_max; t++, txt++)
  280.     {
  281.       l = strlen (&p->chars[txt->text]);
  282.       i = (l + 4) & ~3;
  283.       size = 40 * df->fonts[txt->font]->size;
  284.       font_converttoos (hor_offset + txt->x, ver_offset - txt->y, &x, &y);
  285.       font_converttoos (hor_offset + txt->rx, ver_offset - txt->ty, &j, &k);
  286.  
  287.       x *= 256, y *= 256, j *= 256, k *= 256;
  288.  
  289.       write_n (f, put_out, 4, 1, 52 + i, x, y);
  290.       write_n (f, put_out, 2, j, k);
  291.       write_n (f, put_out, 7, 0, 0xffffff00, dvi_to_font[txt->font], size, size, x, y);
  292.       put_out (&p->chars[txt->text], 1, l, f);
  293.       k = 0;
  294.       for (j = l; j < i; j++)
  295.         put_out (&k, 1, 1, f);
  296.     }
  297.  
  298.   /* Output rules.  */
  299.  
  300.   for (t = 0, rl = p->rules; t < p->rule_max; t++, rl++)
  301.     {
  302.       font_converttoos ((hor_offset + rl->x) * 256,
  303.                         (ver_offset - rl->y) * 256, &x, &y);
  304.       font_converttoos (rl->w * 256, rl->h * 256, &j, &k);
  305.  
  306.       write_n (f, put_out, 6, 2, 24 + 11 * 4, x, y, x + j, y + k);
  307.       write_n (f, put_out, 11, -1, 0, k, 0x20100042, 2, x, y+k/2, 8, x + j, y+k/2, 0);
  308.     }
  309. } /* output_draw */
  310.  
  311. /* EOF */
  312.